package cn.com.nes.site.service.product.handle;

import cn.com.nes.common.exception.BusinessException;
import cn.com.nes.mybatis.agent.ope.entity.ProductSeriesAndEnergy;
import cn.com.nes.site.entity.dto.product.ProductSeriesAndEnergyDTO;
import cn.com.nes.site.entity.em.product.ProductAttributeEnum;
import cn.com.nes.site.entity.vo.product.SaveProductSeriesAndEnergyVO;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 产品能源分类处理器
 */
@Service("productEnergyHandler")
public class ProductEnergyHandler extends ProductAttributeHandler {

    private static final Long PRODUCT_ENERGY_ROOT_NODE_ID = 0L;// parentId=0L 表示节点为根节点

    @Override
    public Integer getNodeType() {
        return ProductAttributeEnum.ENERGY.getKey();
    }

    @Override
    public Long addNode(SaveProductSeriesAndEnergyVO vo) {
        // 处理根节点
        vo.setParentId(Objects.isNull(vo.getParentId()) ? PRODUCT_ENERGY_ROOT_NODE_ID : vo.getParentId());
        // 校验保存
        checkSave(vo);
        // 开始保存节点数据
        ProductSeriesAndEnergy productAttributeEntity = super.getProductAttributeEntity(vo);

        Integer rows = productSeriesAndEnergyMapper.insert(productAttributeEntity);
        if (rows != 1) {
            throw new BusinessException("新增能源分类失败!");
        }
        return productAttributeEntity.getId();
    }

    @Override
    public Long updateNode(SaveProductSeriesAndEnergyVO vo) {
        checkSave(vo);
        checkUpdate(vo);

        // 开始更新数据
        ProductSeriesAndEnergy productSeriesAndEnergy = new ProductSeriesAndEnergy();
        BeanUtils.copyProperties(vo, productSeriesAndEnergy);
        productSeriesAndEnergy.setGmtModified(vo.getOperateDate());
        productSeriesAndEnergy.setGmtModifiedId(vo.getOperateUserId());

        Integer rows = productSeriesAndEnergyMapper.updateById(productSeriesAndEnergy);
        if (rows != 1) {
            throw new BusinessException("修改能源分类失败!");
        }

        // 如果能源类型设置为null需要单独设置
        if (StrUtil.isBlank(productSeriesAndEnergy.getEnergyType())) {
            productSeriesAndEnergyMapper.initEnergyType(productSeriesAndEnergy.getId());
        }
        return productSeriesAndEnergy.getId();
    }

    // 保存前校验 - 校验当前节点的能源类型范围小于父级节点
    private void checkSave(SaveProductSeriesAndEnergyVO vo) {
        if (PRODUCT_ENERGY_ROOT_NODE_ID.equals(vo.getParentId()) || StrUtil.isBlank(vo.getEnergyType())) {
            return;
        }
        // 如果不是根节点,且传了能源分类,需要判断能源分类是否被上级的能源分类包含
        List<ProductSeriesAndEnergyDTO> parentNode = productSeriesAndEnergyMapper.getNodeListById(Collections.singleton(vo.getParentId()));
        if (CollectionUtil.isEmpty(parentNode) || StrUtil.isBlank(parentNode.get(0).getEnergyType())) {
            return;
        }
        Set<String> parentEnergyTypeSet = new HashSet<>(Arrays.asList(parentNode.get(0).getEnergyType().split(",")));
        Set<String> childEnergyTypeSet = new HashSet<>(Arrays.asList(vo.getEnergyType().split(",")));
        childEnergyTypeSet.forEach(childEnergyType -> {
            if (parentEnergyTypeSet.stream().noneMatch(childEnergyType::equals)) {
                throw new BusinessException("当前节点的能源类型不是父级能源类型的子集");
            }
        });
    }

    // 更新前校验 - 校验当前节点的能源类型范围大于下级节点
    private void checkUpdate(SaveProductSeriesAndEnergyVO vo) {
        if (StrUtil.isBlank(vo.getEnergyType())) {
            return;
        }
        // 判断是否已存在下级节点
        List<ProductSeriesAndEnergyDTO> childList = productSeriesAndEnergyMapper.getChildListByParentId(vo.getId(), null);
        if (CollectionUtil.isEmpty(childList)) {
            return;
        }
        HashSet<String> parentEnergyTypeSet = new HashSet<>(Arrays.asList(vo.getEnergyType().split(",")));
        for (ProductSeriesAndEnergyDTO childNode : childList) {
            if (StrUtil.isBlank(childNode.getEnergyType())) {
                continue;
            }
            HashSet<String> childEnergyTypeSet = new HashSet<>(Arrays.asList(childNode.getEnergyType().split(",")));
            childEnergyTypeSet.forEach(childEnergyType -> {
                if (parentEnergyTypeSet.stream().noneMatch(childEnergyType::equals)) {
                    throw new BusinessException("由于子节点存在\"更大范围\"的能源类型,修改节点能源类型失败");
                }
            });
        }
    }


}
